import requests
import logging
import time
import zlib
import sys
from settings import COOKIE, CSRF_TOKEN

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename='updateblibli.txt',
    filemode='a'
)


class DouYin(object):
    def __init__(self, cookie, csrf_token):
        self.UserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'
        self.cookie = cookie
        self.csrf_token = csrf_token
        self.auth, self.ak = self.get_auth_and_ak()

    @staticmethod
    def crc32(filepath):
        block_size = 1024 * 1024
        crc = 0
        fd = open(filepath, 'rb')
        while True:
            buffer = fd.read(block_size)
            if len(buffer) == 0:  # EOF or file empty. return hashes
                fd.close()
                if sys.version_info[0] < 3 and crc < 0:
                    crc += 2 ** 32
                return hex(crc)[2:]
            crc = zlib.crc32(buffer, crc)

    def get_auth_and_ak(self):
        r = requests.get(
            'https://media.douyin.com/web/api/media/upload/auth/',
            headers={
                'cookie': self.cookie,
                'User-Agent': self.UserAgent
            }
        )
        data = r.json()
        return data['auth'], data['ak']

    def upload_video(self, video_path):
        r = requests.get(
            "https://vas-lf-x.snssdk.com/video/openapi/v1/?action=GetVideoUploadParams&use_edge_node=1",
            headers={
                "authorization": self.auth,
                "x-tt-access": self.ak,
                'User-Agent': self.UserAgent
            }
        )
        edge_nodes = r.json()['data']['edge_nodes'][0]

        requests.post(
            url=f"https://{edge_nodes['tos_host']}/{edge_nodes['oid']}",
            headers={
                "Content-CRC32": self.crc32(video_path),
                "Authorization": edge_nodes['tos_sign'],
                'User-Agent': self.UserAgent
            },
            data=open(video_path, 'rb').read()
        )
        return edge_nodes

    def upload_img(self, img_path):
        r = requests.get(
            'https://vas-lf-x.snssdk.com/video/openapi/v1/?action=GetImageUploadParams&use_edge_node=1',
            headers={
                "authorization": self.auth,
                "x-tt-access": self.ak,
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'
            }
        )
        data = r.json()['data']
        r = requests.post(
            url=f"https://{data['tos_host']}/{data['object_ids'][0]}",
            headers={
                "Content-CRC32": self.crc32(img_path),
                "Authorization": data['tos_sign'],
                'User-Agent': self.UserAgent
            },
            data=open(img_path, 'rb').read()
        )
        return data

    def send_upload(self, edge_nodes, img_data, data):
        r = requests.post(
            url=f"https://vas-lf-x.snssdk.com/video/openapi/v1/?action=UpdateVideoUploadInfos&{edge_nodes['extra_param']}",
            headers={
                "authorization": self.auth,
                "x-tt-access": self.ak,
                'User-Agent': self.UserAgent
            },
            json={
                "vid": edge_nodes['vid'],
                "oid": edge_nodes['oid'],
                "token": edge_nodes['token'],
                "poster_ss": 0,
                "is_exact_poster": True,
                "user_reference": ""
            }
        )
        time.sleep(1)
        r = requests.post(
            url="https://media.douyin.com/web/api/media/aweme/create/",
            headers={
                'cookie': self.cookie,
                'x-csrf-token': self.csrf_token,
                'User-Agent': self.UserAgent
            },
            data={
                'video_id': edge_nodes['vid'],
                'poster': edge_nodes['oid'],
                'poster_delay': 0,
                'text': data['title'],
                'text_extra': [],
                'challenges': [],
                'mentions': [],
                'visibility_type': 0,
                'download': 0,
                'upload_source': 1,
                'mix_id': "",
                'mix_order': "",
                'is_preview': 0,
                "cover_optimized_uri": img_data['object_ids'][0]
            }
        )
        return r.json()

    def run(self, data):
        try:
            edge_nodes = self.upload_video(data['video_path'])
            time.sleep(1)
            img_data = self.upload_img(data['img_path'])
            self.send_upload(edge_nodes, img_data, data)
            logging.info("上传抖音成功")
        except Exception as e:
            logging.error(f"上传抖音失败 {e}")


if __name__ == '__main__':
    D = DouYin(
        cookie=COOKIE,
        csrf_token=CSRF_TOKEN
    )
    # D.run(data)
